/*
 * cpe301Project1.asm
 *
 *   Author: Henry Chan
 *
 *	This Assembly code is intended to perform the following functions:
 *		a) Store 25 numbers starting from RAMEND.
 *		b)Parse through the 25 numbers and add all numbers
 *		divisible by 3 and place the result in R20:R21
 *		c)Parse through the 25 numbers and add all numbers
 *		divisible by 7 and place the result in R23:R24
 *		e)X/Y/Z registers are used for parsing the 25 numbers
 *
 *	X=R27:R26=address pointer
 *	Y=R29:R28
 *	Z=R31:R30
 *
 *	R20:21 <- Sum of 3's
 *	R23:24 <- Sum of 7's
 *
 *  RAMMIDDLE=(0x08FF-0x0100)/2=0x04FF
 *  Seed value = 0x04FF + 1 = 0x0500
 *  I add 1 to RAMMIDDLE so the numbers won't be negative (0xFF)
 *
 */ 

// .include "m328def.inc"
 .org 0

 .DEF THREE = R16
	LDI THREE, 3
 .DEF SEVEN = R19
	LDI SEVEN, 7
 .DEF NUM1 = R17
 .DEF NUM2 = R18

	LDI R20, 0		//Initialize R20 to 0
	LDI R21, 0		//Initialize R21 to 0
	LDI R22, 0		//Initialize R22 to 0
	LDI R23, 0		//Initialize R23 to 0
	LDI R24, 0		//Initialize R24 to 0
	LDI R25, 25		//R25 = Count = 20

	LDI R26, low(RAMEND)	//Load address of RAM_END LOW into X LOW
	LDI R27, high(RAMEND)	//Load address of RAM_END HIGH into X HIGH
	LDI R28, 0x00			//Y=0x00 (Seed value = RAMMIDDLE_LOW)

	/* Generate 25 Numbers */

	ADIW R26, 1		//INC X beyond RAM_END
	ADC R27, R22	//because we will pre-decrement X
LOOP:
	ST -X, R28		//[addr]=integer and pre-decrement address
	INC R28			//Inc integer
	DEC R25			//Dec count
	BRNE LOOP		//Loop until 25 numbers are generated

	/* Once the numbers are stored in memory,
	parse through each number, checking for
	divisibility by 3 and 7. */

	LDI R25, 25		//R25 = Count = 25
FETCH:
	LD R28, X+		//R28=[X] then X++
	MOV NUM1, R28	//NUM1 = R28
	MOV NUM2, R28	//NUM2 = R28
L1:
	SUB NUM1, THREE	//Subtract 3 from the number until negative
	BRCC L1			//Branch if not done

	ADD NUM1, THREE //Re-add the '3' that caused negative
	BRNE L2			//If the remainder is not 0, it is not divisible by 3
	ADD R21, R28	//Else Sum3=Sum3+divisByThree
	ADC R20, R22	//R20=R20+0+Carry
L2:
	SUB NUM2, SEVEN	//Subtract 7 from the number until negative
	BRCC L2			//Branch if not done

	ADD NUM2, SEVEN	//Re-add the '7' tha caused negative
	BRNE SKIP		//If the remainder is not 0, it is not divisible by 7
	ADD R24, R28	//Sum7=Sum7+divisBySEVEN
	ADC R23, R22	//R23=R23+0+Carry
SKIP:
	DEC R25			//Count--
	BRNE FETCH		//Continue until all 25 numbers are parsed
	NOP